package com.yhx.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.command.AsyncResult;
import com.yhx.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Future;

/**
 * @author uknow
 * @description
 * @date 2020/6/20 19:36
 */
@Service
public class UserService {

    private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER";

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 同步
     * @param name
     * @return
     */
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")  //设置超时时间，默认为1000ms
            },fallbackMethod = "queryUserByNameFallback")
    public List<User> queryUserByName(String name){
        List users = restTemplate.getForObject(REST_URL_PREFIX + "/user/queryUserByName/" + name, List.class);
        return users;
    }

    /**
     * 线程池隔离
     * @param name
     * @return
     */
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy",value = "THREAD")  //线程池隔离
            },
            threadPoolKey = "queryUserByNameThreadPool",
            threadPoolProperties = {
                @HystrixProperty(name = "coreSize",value = "3"),
                @HystrixProperty(name = "maxQueueSize",value = "5"),
                @HystrixProperty(name = "queueSizeRejectionThreshold",value = "7")
            },
            fallbackMethod = "queryUserByNameFallback")
    public List<User> queryUserByNameThread(String name){
        List users = restTemplate.getForObject(REST_URL_PREFIX + "/user/queryUserByName/" + name, List.class);
        return users;
    }


    /**
     * 信号量隔离
     * @param name
     * @return
     */
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name = "execution.isolation.strategy",value = "SEMAPHORE"),  //信号量隔离
            @HystrixProperty(name = "execution.isolation.semaphore.maxConcurrentRequests",value = "6")
            },
            fallbackMethod = "queryUserByNameFallback")
    public List<User> queryUserByNameSemaphore(String name){
        List users = restTemplate.getForObject(REST_URL_PREFIX + "/user/queryUserByName/" + name, List.class);
        return users;
    }

    public List<User> queryUserByNameFallback(String name){
        User user = new User().setId(0).setName("查询"+name+"时，客户端发生了服务降级");
        List<User> users = new ArrayList<User>();
        users.add(user);
        return users;
    }

    /**
     * 异步
     * @param name
     * @return
     */
    @HystrixCommand(fallbackMethod = "queryUserByNameFallback")
    public Future<List<User>> queryUserByNameAsync(final String name){
        return new AsyncResult<List<User>>() {
            @Override
            public List<User> invoke() {
                return restTemplate.getForObject(REST_URL_PREFIX + "/user/queryUserByName/" + name, List.class);
            }
        };
    }
}
